#import "CTBaseWebVC.h"
#import <ContactsUI/ContactsUI.h>
#import <WebKit/WebKit.h>
#import "Reachability.h"
#import "NSDictionary+WBJSONString.h"
#import "BaseNetRequest.h"
#import "CTLocationModel.h"
@interface WeakWebViewScriptMessageDelegate : NSObject<WKScriptMessageHandler,UIScrollViewDelegate, CNContactPickerDelegate>
@property (nonatomic, weak) id<WKScriptMessageHandler> scriptDelegate;
-(instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate;
@end
@implementation WeakWebViewScriptMessageDelegate
-(instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate {
    self = [super init];
    if (self) {
        _scriptDelegate = scriptDelegate;
    }
    return self;
}
#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if ([self.scriptDelegate respondsToSelector:@selector(userContentController:didReceiveScriptMessage:)]) {
        [self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message];
    }
}
@end
@interface CTBaseWebVC ()  <WKUIDelegate,WKNavigationDelegate,UIScrollViewDelegate>
@property (nonatomic, strong) UIProgressView * progressView;
@property (nonatomic ,strong) NSString *titleStr;
@property (nonatomic ,strong) UIColor *bgColor;
@property (nonatomic ,assign) BOOL isObserve;
@property (nonatomic ,assign) BOOL isChangeColor;
@property (nonatomic ,assign) int h5NavType;
@property (nonatomic ,assign) BOOL isSingLeft;
@property (nonatomic ,strong) CNContact *selctContact;
@end
@implementation CTBaseWebVC
- (id)initWithTitle:(NSString *)title gotoUrl:(NSString *)gotoUrl
{
    if (self = [super init])
    {
        _isSingLeft = NO;
        _isChangeColor = NO;
        _isObserve = NO;
        _h5NavType = 0;
        if (beNil(gotoUrl)) {
            gotoUrl = @"";
        }
        if ([gotoUrl hasPrefix:@"www."]) {
            gotoUrl = [NSString stringWithFormat:@"http://%@",gotoUrl];
        }
        _url = gotoUrl;
        _titleStr = title;
    }
    return self;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupUI];
}
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    if (_isChangeColor) {
        self.webView.scrollView.backgroundColor = self.bgColor;
    }
}
#pragma mark - privateMethods
- (void)setupUI
{
    self.var_hiddenNavigationBar = YES;
    [self.view addSubview:self.webView];
    [self.view addSubview:self.progressView];
    self.webView.scrollView.delegate = self;
    if (@available(iOS 11.0, *)) {
        self.webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    } else {
        self.automaticallyAdjustsScrollViewInsets = NO;
    }
    [self.webView addObserver:self
                   forKeyPath:NSStringFromSelector(@selector(estimatedProgress))
                      options:0
                      context:nil];
    [self.webView addObserver:self
                   forKeyPath:@"title"
                      options:NSKeyValueObservingOptionNew
                      context:nil];
    [self checkNetworkReachability];
    @weakify(self);
    [RACObserve(self.webView, canGoBack) subscribeNext:^(id x) {
        @strongify(self);
    }];
}
- (void)checkNetworkReachability
{
}
- (void)observeScrollOffset
{
    self.title = nil;
    _isObserve = YES;
}
- (void)startRequest
{
    NSLog(@"web url = %@",self.url);
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]];
    [request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
    [request addValue:[self readCurrentCookieWithDomain:self.url] forHTTPHeaderField:@"Cookie"];
    if ([self.url hasPrefix:@"file"]) {
        NSURL *url = [NSURL URLWithString:self.url];
        [_webView loadFileURL:url allowingReadAccessToURL:url];
    }else
    {
        [_webView loadRequest:request];
    }
}
#pragma mark - register JS。
- (void)registerWebHandler
{
}
#pragma mark  kvo
-(void)observeValueForKeyPath:(NSString *)keyPath
                     ofObject:(id)object
                       change:(NSDictionary<NSKeyValueChangeKey,id> *)change
                      context:(void *)context{
    if ([keyPath isEqualToString:NSStringFromSelector(@selector(estimatedProgress))]
        && object == _webView) {
        self.progressView.progress = _webView.estimatedProgress;
        if (_webView.estimatedProgress >= 1.0f) {
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                self.progressView.progress = 0;
            });
        }
    }else if([keyPath isEqualToString:@"title"]
             && object == _webView){
    }else{
        [super observeValueForKeyPath:keyPath
                             ofObject:object
                               change:change
                              context:context];
    }
}
#pragma mark -- scrollDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (!_isObserve) {
        return;
    }
    if (_h5NavType) {
        return;
    }
    CGFloat y = scrollView.contentOffset.y;
    if (y >= 50) {
        self.topBar.var_titleLabel.text = self.titleStr;
    }else{
        self.topBar.var_titleLabel.text = @"";
    }
    if (_isSingLeft) {
        return;
    }
    if (self.isObserve) {
        CGFloat alpha = y/[UIDevice ct_fullNavHeight];;
        if (alpha > 1) {
            alpha = 1;
            _isChangeColor = NO;
            [self setNeedsStatusBarAppearanceUpdate];
        }
        else if (alpha < 0) {
            [self setNeedsStatusBarAppearanceUpdate];
            _isChangeColor = YES;
            alpha = 0;
        }
        [self.topBar ct_changeBackgroundViewAlpha:alpha];
    }
}
#pragma mark - PublicMthods
- (void)showRootVCStyle
{
    self.topBar.backView.hidden = YES;
    [self.topBar ct_hideCloseBtn];
    self.topBar.var_titleLabel.text = self.titleStr;
    [self.view addSubview:self.topBar];
    [self.topBar ct_changeBackgroundViewAlpha:0];
    self.topBar.backgroundColor = [UIColor whiteColor];
    self.webView.ct_y = self.topBar.ct_bottom;
    self.webView.ct_height = [UIDevice ct_viewHeight];
    self.progressView.ct_y = self.topBar.ct_bottom;
    _isObserve = NO;
}
- (void)showLeftSingleBack
{
    [self showLeftBackTransparent];
    self.topBar.backView.hidden = NO;
    [self.topBar ct_hideCloseBtn];
    [self.topBar ct_changeBackgroundViewAlpha:1.0];
    self.webView.ct_y = self.topBar.ct_bottom;
    self.webView.ct_height = [UIDevice ct_viewHeight];
    self.progressView.ct_y = self.topBar.ct_bottom;
    _isObserve = NO;
}
- (void)showLeftSingleBackNotitleTextScroll
{
    [self.view addSubview:self.topBar];
    [self.topBar ct_changeBackgroundViewAlpha:1.0];
    [self.topBar ct_setBackArrowBlack];
    [self.topBar ct_hideCloseBtn];
    self.webView.ct_y = self.topBar.ct_bottom;
    self.progressView.ct_y = self.topBar.ct_bottom;
    self.webView.ct_height = self.view.ct_height-self.topBar.ct_height;
    _isObserve = YES;
    _isSingLeft = YES;
}
- (void)showLeftSingleBackTransparent
{
    [self showLeftBackTransparent];
    [self.topBar ct_hideCloseBtn];
    _isObserve = YES;
}
- (void)showLeftBackClose
{
    [self showLeftBackTransparent];
    [self.topBar ct_changeBackgroundViewAlpha:1.0];
    self.webView.ct_y = self.topBar.ct_bottom;
    self.webView.ct_height = [UIDevice ct_viewHeight];
    self.progressView.ct_y = self.topBar.ct_bottom;
    _isObserve = NO;
}
- (void)showRightBackClose {
    self.topBar.var_titleLabel.text = self.titleStr;
    self.topBar.var_msgCenterBtn.hidden = NO;
    [self.view addSubview:self.topBar];
    [self.topBar ct_changeBackgroundViewAlpha:0];
    self.webView.ct_y = [UIDevice ct_statusBarHeight];
    self.webView.ct_height = [UIDevice ct_screenHeight]-[UIDevice ct_statusBarHeight];
    self.progressView.ct_y = [UIDevice ct_statusBarHeight];
    _isObserve = NO;
}
- (void)showLeftBackTransparent
{
    self.topBar.var_titleLabel.text = self.titleStr;
    [self.view addSubview:self.topBar];
    [self.topBar ct_changeBackgroundViewAlpha:0];
    self.webView.ct_y = 0;
    self.webView.ct_height = self.view.ct_height;
    self.progressView.ct_y = 0;
    _isObserve = YES;
}
- (void)showTitle
{
    [self ct_setNavTitle:self.titleStr];
}
- (void)showLeftButton:(BOOL)isShow
{
    self.topBar.backView.hidden = !isShow;
}
- (void)showOnlineServiceButton:(BOOL)isShow
{
    self.topBar.var_onlineServiceBtn.hidden = !isShow;
}
- (void)showMsgCenterButton:(BOOL)isShow
{
    self.topBar.var_msgCenterBtn.hidden = !isShow;
    self.topBar.var_textBtn.hidden = isShow;
}
- (void)showTestButton:(BOOL)isShow
{
    self.topBar.var_textBtn.hidden = !isShow;
    self.topBar.var_msgCenterBtn.hidden = isShow;
}
- (void)hideMsgAndTextButton {
    self.topBar.var_textBtn.hidden = YES;
    self.topBar.var_msgCenterBtn.hidden = YES;
}
- (void)setBackgroundColor:(UIColor *)color;
{
    _isChangeColor = YES;
    [self setNeedsStatusBarAppearanceUpdate];
}
- (void)setWebviewFrame:(CGRect)frame {
    self.webView.frame = frame;
}
-(UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleDarkContent;
}
#pragma mark -- Event Handle
- (void)goBackAction:(id)sender{
    if ([self.webView canGoBack]) {
        [self.webView goBack];
    } else {
        [self back];
    }
}
- (void)refreshAction:(id)sender{
    [_webView reload];
}
- (void)back
{
    [self.navigationController popViewControllerAnimated:YES];
}
- (void)getCookie{
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    NSString *JSFuncString =
    @"function setCookie(name,value,expires)\
    {\
    var oDate=new Date();\
    oDate.setDate(oDate.getDate()+expires);\
    document.cookie=name+'='+value+';expires='+oDate+';path=/'\
    }\
    function getCookie(name)\
    {\
    var arr = document.cookie.match(new RegExp('(^| )'+name+'=([^;]*)(;|$)'));\
    if(arr != null) return unescape(arr[2]); return null;\
    }\
    function delCookie(name)\
    {\
    var exp = new Date();\
    exp.setTime(exp.getTime() - 1);\
    var cval=getCookie(name);\
    if(cval!=null) document.cookie= name + '='+cval+';expires='+exp.toGMTString();\
    }";
    NSMutableString *JSCookieString = JSFuncString.mutableCopy;
    for (NSHTTPCookie *cookie in cookieStorage.cookies) {
        NSString *excuteJSString = [NSString stringWithFormat:@"setCookie('%@', '%@', 1);", cookie.name, cookie.value];
        [JSCookieString appendString:excuteJSString];
    }
    [_webView evaluateJavaScript:JSCookieString completionHandler:nil];
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
    NSDictionary * parameter = message.body;
    if([message.name isEqualToString:@"jsToOcNoPrams"]){
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"js -> oc" message:@"parameterless" preferredStyle:UIAlertControllerStyleAlert];
        [alertController addAction:([UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        }])];
        [self presentViewController:alertController animated:YES completion:nil];
    }else if([message.name isEqualToString:@"jsToOcWithPrams"]){
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"js -> oc" message:parameter[@"params"] preferredStyle:UIAlertControllerStyleAlert];
        [alertController addAction:([UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        }])];
        [self presentViewController:alertController animated:YES completion:nil];
    }
}
#pragma mark -- WKNavigationDelegate
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
    NSLog(@"page start loading----");
}
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
    [self.progressView setProgress:0.0f animated:NO];
}
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
}
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    [self.progressView setProgress:0.0f animated:NO];
}
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    NSString * urlStr = navigationAction.request.URL.absoluteString;
    NSURL *URL = navigationAction.request.URL;
    NSString *jumpUrl = URL.absoluteString;
    NSString *scheme = [URL absoluteString];
    NSLog(@"homeWebUrl = %@",scheme);
    if ([scheme isEqualToString:@"jsb://action=goBack"]) {
        [self.navigationController popViewControllerAnimated:YES];
        decisionHandler(WKNavigationActionPolicyCancel);
        return;
    }
    NSString *htmlHeadString = @"github://";
    if([urlStr hasPrefix:htmlHeadString]){
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Call OC by intercepting the URL" message:@"Would you like to visit my Github page?" preferredStyle:UIAlertControllerStyleAlert];
        [alertController addAction:([UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        }])];
        [alertController addAction:([UIAlertAction actionWithTitle:@"Open" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            NSURL * url = [NSURL URLWithString:[urlStr stringByReplacingOccurrencesOfString:@"github://callName_?" withString:@""]];
            [[UIApplication sharedApplication] openURL:url];
        }])];
        [self presentViewController:alertController animated:YES completion:nil];
        decisionHandler(WKNavigationActionPolicyCancel);
    }else{
        decisionHandler(WKNavigationActionPolicyAllow);
    }
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
    NSString * urlStr = navigationResponse.response.URL.absoluteString;
    decisionHandler(WKNavigationResponsePolicyAllow);
}
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
    NSURLCredential * newCred = [[NSURLCredential alloc] initWithUser:@"user123" password:@"123" persistence:NSURLCredentialPersistenceNone];
    [challenge.sender useCredential:newCred forAuthenticationChallenge:challenge];
    completionHandler(NSURLSessionAuthChallengeUseCredential,newCred);
}
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView{
}
#pragma mark -- WKUIDelegate
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"HTML pop-up box" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }])];
    [alertController addAction:([UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.text = defaultText;
    }];
    [alertController addAction:([UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(alertController.textFields[0].text?:@"");
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
    if (!navigationAction.targetFrame.isMainFrame) {
        [webView loadRequest:navigationAction.request];
    }
    return nil;
}
- (void)dealloc{
    [[_webView configuration].userContentController removeScriptMessageHandlerForName:@"jsToOcNoPrams"];
    [[_webView configuration].userContentController removeScriptMessageHandlerForName:@"jsToOcWithPrams"];
    [_webView removeObserver:self
                  forKeyPath:NSStringFromSelector(@selector(estimatedProgress))];
    [_webView removeObserver:self
                  forKeyPath:NSStringFromSelector(@selector(title))];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}
#pragma mark - lazyLoading
- (UIProgressView *)progressView
{
    if (!_progressView){
        _progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 1, self.view.frame.size.width, 2)];
        _progressView.tintColor = [UIColor colorFF8400];
        _progressView.trackTintColor = [UIColor clearColor];
    }
    return _progressView;
}
- (WKWebView *)webView{
    if(_webView == nil){
        WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
        WKPreferences *preference = [[WKPreferences alloc]init];
        preference.minimumFontSize = 0;
        preference.javaScriptEnabled = YES;
        preference.javaScriptCanOpenWindowsAutomatically = YES;
        config.preferences = preference;
        config.allowsInlineMediaPlayback = YES;
        config.requiresUserActionForMediaPlayback = YES;
        config.allowsPictureInPictureMediaPlayback = YES;
        config.applicationNameForUserAgent = @"ChinaDailyForiPad";
        WeakWebViewScriptMessageDelegate *weakScriptMessageDelegate = [[WeakWebViewScriptMessageDelegate alloc] initWithDelegate:self];
        WKUserContentController * wkUController = [[WKUserContentController alloc] init];
        [wkUController addScriptMessageHandler:weakScriptMessageDelegate  name:@"jsToOcNoPrams"];
        [wkUController addScriptMessageHandler:weakScriptMessageDelegate  name:@"jsToOcWithPrams"];
        config.userContentController = wkUController;
        _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, self.view.ct_height) configuration:config];
        _webView.UIDelegate = self;
        _webView.navigationDelegate = self;
        _webView.allowsBackForwardNavigationGestures = YES;
        WKBackForwardList * backForwardList = [_webView backForwardList];
    }
    return _webView;
}
- (NSString *)readCurrentCookieWithDomain:(NSString *)domainStr{
    NSHTTPCookieStorage*cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    NSMutableString * cookieString = [[NSMutableString alloc]init];
    for (NSHTTPCookie*cookie in [cookieJar cookies]) {
        [cookieString appendFormat:@"%@=%@;",cookie.name,cookie.value];
    }
    if ([cookieString hasSuffix:@";"]) {
        [cookieString deleteCharactersInRange:NSMakeRange(cookieString.length - 1, 1)];
    }
    return cookieString;
}
- (CTWebBar *)topBar
{
    if (!_topBar) {
        _topBar = [[CTWebBar alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, [UIDevice ct_fullNavHeight])];
        _topBar.var_titleLabel.text = @"";
        _topBar.var_closeView.hidden = YES;
        @weakify(self);
        [_topBar.var_backClickSubject subscribeNext:^(id x) {
            @strongify(self);
            [self goBackAction:nil];
        }];
        [_topBar.var_closeClickSubject subscribeNext:^(id x) {
            @strongify(self);
            [self back];
        }];
        [_topBar.var_msgCenterClickSubject subscribeNext:^(id x) {
            @strongify(self);
            [self back];
        }];
    }
    return _topBar;
}
- (WKWebViewJavascriptBridge *)bridge
{
    if (_bridge) {
        return _bridge;
    }
    _bridge = [WKWebViewJavascriptBridge bridgeForWebView:self.webView];
    return _bridge;
}
- (NSString *)getUrl {
    return self.url;
}
@end
